#pragma once

#include "cublas_api_wrapper.h"

#if defined(__cplusplus)
extern "C" {
#endif

/* CUBLAS data types */
#define cublasStatus mcblasStatus_t

#define cuComplex mcComplex
#define cuDoubleComplex mcDoubleComplex
static mcblasHandle_t handle__;
static mcblasStatus_t status__;

static cublasStatus cublasInit(void) {
    status__ = mcblasCreate(&handle__);
    return status__;
}
static cublasStatus cublasShutdown(void) {
    status__ = mcblasDestroy(handle__);
    return status__;
}
static cublasStatus cublasGetError(void) {
    mcblasStatus_t status = status__;
    status__ = MCBLAS_STATUS_SUCCESS;
    return status;
}

static cublasStatus cublasGetVersion(int* version) {
    status__ = mcblasGetVersion(handle__, version);
    return status__;
}
static cublasStatus cublasAlloc(int n, int elemSize, void** devicePtr) {
    status__ = MCBLAS_STATUS_SUCCESS;
    int ret = mcMalloc(devicePtr, n * elemSize);
    if (ret != 0) {
        status__ = MCBLAS_STATUS_ALLOC_FAILED;
    }
    return status__;
}

static cublasStatus cublasFree(void* devicePtr) {
    status__ = MCBLAS_STATUS_SUCCESS;
    int ret = mcFree(devicePtr);
    if (ret != 0) {
        status__ = MCBLAS_STATUS_ALLOC_FAILED;
    }
    return status__;
}

static cublasStatus cublasSetKernelStream(cudaStream_t stream) {
    status__ = mcblasSetStream(handle__, stream);
    return status__;
}

/* ---------------- CUBLAS BLAS1 functions ---------------- */
/* NRM2 */
static float cublasSnrm2(int n, const float* x, int incx) {
    float result = 0.0;
    status__ = mcblasSnrm2(handle__, n, x, incx, &result);
    return result;
}
static double cublasDnrm2(int n, const double* x, int incx) {
    double result = 0.0;
    status__ = mcblasDnrm2(handle__, n, x, incx, &result);
    return result;
}
static float cublasScnrm2(int n, const cuComplex* x, int incx) {
    float result = 0.0;
    status__ = mcblasScnrm2(handle__, n, x, incx, &result);
    return result;
}
static double cublasDznrm2(int n, const cuDoubleComplex* x, int incx) {
    double result = 0.0;
    status__ = mcblasDznrm2(handle__, n, x, incx, &result);
    return result;
}
/*------------------------------------------------------------------------*/
/* DOT */
static float cublasSdot(int n, const float* x, int incx, const float* y, int incy) {
    float result = 0.0;
    status__ = mcblasSdot(handle__, n, x, incx, y, incy, &result);
    return result;
}
static double cublasDdot(int n, const double* x, int incx, const double* y, int incy) {
    double result = 0.0;
    status__ = mcblasDdot(handle__, n, x, incx, y, incy, &result);
    return result;
}
cuComplex static cublasCdotu(int n, const cuComplex* x, int incx, const cuComplex* y, int incy) {
    mcComplex result = {0.0, 0.0};
    status__ = mcblasCdotu(handle__, n, x, incx, y, incy, &result);
    return result;
}
cuComplex static cublasCdotc(int n, const cuComplex* x, int incx, const cuComplex* y, int incy) {
    mcComplex result = {0.0, 0.0};
    status__ = mcblasCdotc(handle__, n, x, incx, y, incy, &result);
    return result;
}
cuDoubleComplex static cublasZdotu(int n,
                                   const cuDoubleComplex* x,
                                   int incx,
                                   const cuDoubleComplex* y,
                                   int incy) {
    mcDoubleComplex result = {0.0, 0.0};
    status__ = mcblasZdotu(handle__, n, x, incx, y, incy, &result);
    return result;
}
cuDoubleComplex static cublasZdotc(int n,
                                   const cuDoubleComplex* x,
                                   int incx,
                                   const cuDoubleComplex* y,
                                   int incy) {
    mcDoubleComplex result = {0.0, 0.0};
    status__ = mcblasZdotc(handle__, n, x, incx, y, incy, &result);
    return result;
}
/*------------------------------------------------------------------------*/
/* SCAL */
static void cublasSscal(int n, float alpha, float* x, int incx) {
    status__ = mcblasSscal(handle__, n, &alpha, x, incx);
}
static void cublasDscal(int n, double alpha, double* x, int incx) {
    status__ = mcblasDscal(handle__, n, &alpha, x, incx);
}
static void cublasCscal(int n, cuComplex alpha, cuComplex* x, int incx) {
    status__ = mcblasCscal(handle__, n, &alpha, x, incx);
}
static void cublasZscal(int n, cuDoubleComplex alpha, cuDoubleComplex* x, int incx) {
    status__ = mcblasZscal(handle__, n, &alpha, x, incx);
}

static void cublasCsscal(int n, float alpha, cuComplex* x, int incx) {
    status__ = mcblasCsscal(handle__, n, &alpha, x, incx);
}
static void cublasZdscal(int n, double alpha, cuDoubleComplex* x, int incx) {
    status__ = mcblasZdscal(handle__, n, &alpha, x, incx);
}
/*------------------------------------------------------------------------*/
/* AXPY */
static void cublasSaxpy(int n, float alpha, const float* x, int incx, float* y, int incy) {
    status__ = mcblasSaxpy(handle__, n, &alpha, x, incx, y, incy);
}
static void cublasDaxpy(int n, double alpha, const double* x, int incx, double* y, int incy) {
    status__ = mcblasDaxpy(handle__, n, &alpha, x, incx, y, incy);
}
static void
    cublasCaxpy(int n, cuComplex alpha, const cuComplex* x, int incx, cuComplex* y, int incy) {
    status__ = mcblasCaxpy(handle__, n, &alpha, x, incx, y, incy);
}
static void cublasZaxpy(int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* x,
                        int incx,
                        cuDoubleComplex* y,
                        int incy) {
    status__ = mcblasZaxpy(handle__, n, &alpha, x, incx, y, incy);
}
/*------------------------------------------------------------------------*/
/* COPY */
static void cublasScopy(int n, const float* x, int incx, float* y, int incy) {
    status__ = mcblasScopy(handle__, n, x, incx, y, incy);
}
static void cublasDcopy(int n, const double* x, int incx, double* y, int incy) {
    status__ = mcblasDcopy(handle__, n, x, incx, y, incy);
}
static void cublasCcopy(int n, const cuComplex* x, int incx, cuComplex* y, int incy) {
    status__ = mcblasCcopy(handle__, n, x, incx, y, incy);
}
static void cublasZcopy(int n, const cuDoubleComplex* x, int incx, cuDoubleComplex* y, int incy) {
    status__ = mcblasZcopy(handle__, n, x, incx, y, incy);
}
/*------------------------------------------------------------------------*/
/* SWAP */
static void cublasSswap(int n, float* x, int incx, float* y, int incy) {
    status__ = mcblasSswap(handle__, n, x, incx, y, incy);
}
static void cublasDswap(int n, double* x, int incx, double* y, int incy) {
    status__ = mcblasDswap(handle__, n, x, incx, y, incy);
}
static void cublasCswap(int n, cuComplex* x, int incx, cuComplex* y, int incy) {
    status__ = mcblasCswap(handle__, n, x, incx, y, incy);
}
static void cublasZswap(int n, cuDoubleComplex* x, int incx, cuDoubleComplex* y, int incy) {
    status__ = mcblasZswap(handle__, n, x, incx, y, incy);
}
/*------------------------------------------------------------------------*/
/* AMAX */
static int cublasIsamax(int n, const float* x, int incx) {
    int result = 0;
    status__ = mcblasIsamax(handle__, n, x, incx, &result);
    return result;
}
static int cublasIdamax(int n, const double* x, int incx) {
    int result = 0;
    status__ = mcblasIdamax(handle__, n, x, incx, &result);
    return result;
}
static int cublasIcamax(int n, const cuComplex* x, int incx) {
    int result = 0;
    status__ = mcblasIcamax(handle__, n, x, incx, &result);
    return result;
}
static int cublasIzamax(int n, const cuDoubleComplex* x, int incx) {
    int result = 0;
    status__ = mcblasIzamax(handle__, n, x, incx, &result);
    return result;
}
/*------------------------------------------------------------------------*/
/* AMIN */
static int cublasIsamin(int n, const float* x, int incx) {
    int result = 0;
    status__ = mcblasIsamin(handle__, n, x, incx, &result);
    return result;
}
static int cublasIdamin(int n, const double* x, int incx) {
    int result = 0;
    status__ = mcblasIdamin(handle__, n, x, incx, &result);
    return result;
}

static int cublasIcamin(int n, const cuComplex* x, int incx) {
    int result = 0;
    status__ = mcblasIcamin(handle__, n, x, incx, &result);
    return result;
}
static int cublasIzamin(int n, const cuDoubleComplex* x, int incx) {
    int result = 0;
    status__ = mcblasIzamin(handle__, n, x, incx, &result);
    return result;
}
/*------------------------------------------------------------------------*/
/* ASUM */
static float cublasSasum(int n, const float* x, int incx) {
    float result = 0;
    status__ = mcblasSasum(handle__, n, x, incx, &result);
    return result;
}
static double cublasDasum(int n, const double* x, int incx) {
    double result = 0;
    status__ = mcblasDasum(handle__, n, x, incx, &result);
    return result;
}
static float cublasScasum(int n, const cuComplex* x, int incx) {
    float result = 0;
    status__ = mcblasScasum(handle__, n, x, incx, &result);
    return result;
}
static double cublasDzasum(int n, const cuDoubleComplex* x, int incx) {
    double result = 0;
    status__ = mcblasDzasum(handle__, n, x, incx, &result);
    return result;
}
/*------------------------------------------------------------------------*/
/* ROT */
static void cublasSrot(int n, float* x, int incx, float* y, int incy, float sc, float ss) {
    status__ = mcblasSrot(handle__, n, x, incx, y, incy, &sc, &ss);
}
static void cublasDrot(int n, double* x, int incx, double* y, int incy, double sc, double ss) {
    status__ = mcblasDrot(handle__, n, x, incx, y, incy, &sc, &ss);
}
static void
    cublasCrot(int n, cuComplex* x, int incx, cuComplex* y, int incy, float c, cuComplex s) {
    status__ = mcblasCrot(handle__, n, x, incx, y, incy, &c, &s);
}
static void cublasZrot(int n,
                       cuDoubleComplex* x,
                       int incx,
                       cuDoubleComplex* y,
                       int incy,
                       double sc,
                       cuDoubleComplex cs) {
    status__ = mcblasZrot(handle__, n, x, incx, y, incy, &sc, &cs);
}
static void cublasCsrot(int n, cuComplex* x, int incx, cuComplex* y, int incy, float c, float s) {
    status__ = mcblasCsrot(handle__, n, x, incx, y, incy, &c, &s);
}
static void cublasZdrot(int n,
                        cuDoubleComplex* x,
                        int incx,
                        cuDoubleComplex* y,
                        int incy,
                        double c,
                        double s) {
    status__ = mcblasZdrot(handle__, n, x, incx, y, incy, &c, &s);
}
/*------------------------------------------------------------------------*/
/* ROTG */
static void cublasSrotg(float* sa, float* sb, float* sc, float* ss) {
    status__ = mcblasSrotg(handle__, sa, sb, sc, ss);
}
static void cublasDrotg(double* sa, double* sb, double* sc, double* ss) {
    status__ = mcblasDrotg(handle__, sa, sb, sc, ss);
}
static void cublasCrotg(cuComplex* ca, cuComplex cb, float* sc, cuComplex* cs) {
    status__ = mcblasCrotg(handle__, ca, &cb, sc, cs);
}
static void cublasZrotg(cuDoubleComplex* ca, cuDoubleComplex cb, double* sc, cuDoubleComplex* cs) {
    status__ = mcblasZrotg(handle__, ca, &cb, sc, cs);
}
/*------------------------------------------------------------------------*/
/* ROTM */
static void cublasSrotm(int n, float* x, int incx, float* y, int incy, const float* sparam) {
    status__ = mcblasSrotm(handle__, n, x, incx, y, incy, sparam);
}
static void cublasDrotm(int n, double* x, int incx, double* y, int incy, const double* sparam) {
    status__ = mcblasDrotm(handle__, n, x, incx, y, incy, sparam);
}
/*------------------------------------------------------------------------*/
/* ROTMG */
static void cublasSrotmg(float* sd1, float* sd2, float* sx1, const float* sy1, float* sparam) {
    status__ = mcblasSrotmg(handle__, sd1, sd2, sx1, sy1, sparam);
}
static void cublasDrotmg(double* sd1, double* sd2, double* sx1, const double* sy1, double* sparam) {
    status__ = mcblasDrotmg(handle__, sd1, sd2, sx1, sy1, sparam);
}

static const mcblasOperation_t char2mcblas_operation(char value) {
    switch (value) {
        case 'N':
        case 'n':
            return MCBLAS_OP_N;
        case 'T':
        case 't':
            return MCBLAS_OP_T;
        case 'C':
        case 'c':
            return MCBLAS_OP_C;
        default:
            return (mcblasOperation_t)(-1);
    }
}

static const mcblasFillMode_t char2mcblas_fill(char value) {
    switch (value) {
        case 'U':
        case 'u':
            return MCBLAS_FILL_MODE_UPPER;
        case 'L':
        case 'l':
            return MCBLAS_FILL_MODE_LOWER;
        default:
            return (mcblasFillMode_t)(-1);
    }
}

static const mcblasDiagType_t char2mcblas_diagonal(char value) {
    switch (value) {
        case 'U':
        case 'u':
            return MCBLAS_DIAG_UNIT;
        case 'N':
        case 'n':
            return MCBLAS_DIAG_NON_UNIT;
        default:
            return (mcblasDiagType_t)(-1);
    }
}

static const mcblasSideMode_t char2mcblas_side(char value) {
    switch (value) {
        case 'L':
        case 'l':
            return MCBLAS_SIDE_LEFT;
        case 'R':
        case 'r':
            return MCBLAS_SIDE_RIGHT;
        default:
            return (mcblasSideMode_t)(-1);
    }
}

/* --------------- CUBLAS BLAS2 functions  ---------------- */
/* GEMV */
static void cublasSgemv(char trans,
                        int m,
                        int n,
                        float alpha,
                        const float* A,
                        int lda,
                        const float* x,
                        int incx,
                        float beta,
                        float* y,
                        int incy) {
    status__ = mcblasSgemv(handle__, char2mcblas_operation(trans), m, n, &alpha, A, lda, x, incx,
                           &beta, y, incy);
}
static void cublasDgemv(char trans,
                        int m,
                        int n,
                        double alpha,
                        const double* A,
                        int lda,
                        const double* x,
                        int incx,
                        double beta,
                        double* y,
                        int incy) {
    status__ = mcblasDgemv(handle__, char2mcblas_operation(trans), m, n, &alpha, A, lda, x, incx,
                           &beta, y, incy);
}
static void cublasCgemv(char trans,
                        int m,
                        int n,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        const cuComplex* x,
                        int incx,
                        cuComplex beta,
                        cuComplex* y,
                        int incy) {
    status__ = mcblasCgemv(handle__, char2mcblas_operation(trans), m, n, &alpha, A, lda, x, incx,
                           &beta, y, incy);
}
static void cublasZgemv(char trans,
                        int m,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        const cuDoubleComplex* x,
                        int incx,
                        cuDoubleComplex beta,
                        cuDoubleComplex* y,
                        int incy) {
    status__ = mcblasZgemv(handle__, char2mcblas_operation(trans), m, n, &alpha, A, lda, x, incx,
                           &beta, y, incy);
}
/*------------------------------------------------------------------------*/
/* GBMV */
static void cublasSgbmv(char trans,
                        int m,
                        int n,
                        int kl,
                        int ku,
                        float alpha,
                        const float* A,
                        int lda,
                        const float* x,
                        int incx,
                        float beta,
                        float* y,
                        int incy) {
    status__ = mcblasSgbmv(handle__, char2mcblas_operation(trans), m, n, kl, ku, &alpha, A, lda, x,
                           incx, &beta, y, incy);
}
static void cublasDgbmv(char trans,
                        int m,
                        int n,
                        int kl,
                        int ku,
                        double alpha,
                        const double* A,
                        int lda,
                        const double* x,
                        int incx,
                        double beta,
                        double* y,
                        int incy) {
    status__ = mcblasDgbmv(handle__, char2mcblas_operation(trans), m, n, kl, ku, &alpha, A, lda, x,
                           incx, &beta, y, incy);
}
static void cublasCgbmv(char trans,
                        int m,
                        int n,
                        int kl,
                        int ku,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        const cuComplex* x,
                        int incx,
                        cuComplex beta,
                        cuComplex* y,
                        int incy) {
    status__ = mcblasCgbmv(handle__, char2mcblas_operation(trans), m, n, kl, ku, &alpha, A, lda, x,
                           incx, &beta, y, incy);
}
static void cublasZgbmv(char trans,
                        int m,
                        int n,
                        int kl,
                        int ku,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        const cuDoubleComplex* x,
                        int incx,
                        cuDoubleComplex beta,
                        cuDoubleComplex* y,
                        int incy) {
    status__ = mcblasZgbmv(handle__, char2mcblas_operation(trans), m, n, kl, ku, &alpha, A, lda, x,
                           incx, &beta, y, incy);
}
/*------------------------------------------------------------------------*/
/* TRMV */
static void cublasStrmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const float* A,
                        int lda,
                        float* x,
                        int incx) {
    status__ = mcblasStrmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, A, lda, x, incx);
}
static void cublasDtrmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const double* A,
                        int lda,
                        double* x,
                        int incx) {
    status__ = mcblasDtrmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, A, lda, x, incx);
}
static void cublasCtrmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const cuComplex* A,
                        int lda,
                        cuComplex* x,
                        int incx) {
    status__ = mcblasCtrmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, A, lda, x, incx);
}
static void cublasZtrmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const cuDoubleComplex* A,
                        int lda,
                        cuDoubleComplex* x,
                        int incx) {
    status__ = mcblasZtrmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, A, lda, x, incx);
}
/*------------------------------------------------------------------------*/
/* TBMV */
static void cublasStbmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        int k,
                        const float* A,
                        int lda,
                        float* x,
                        int incx) {
    status__ = mcblasStbmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, k, A, lda, x, incx);
}
static void cublasDtbmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        int k,
                        const double* A,
                        int lda,
                        double* x,
                        int incx) {
    status__ = mcblasDtbmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, k, A, lda, x, incx);
}
static void cublasCtbmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        int k,
                        const cuComplex* A,
                        int lda,
                        cuComplex* x,
                        int incx) {
    status__ = mcblasCtbmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, k, A, lda, x, incx);
}
static void cublasZtbmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        int k,
                        const cuDoubleComplex* A,
                        int lda,
                        cuDoubleComplex* x,
                        int incx) {
    status__ = mcblasZtbmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, k, A, lda, x, incx);
}
/*------------------------------------------------------------------------*/
/* TPMV */
static void
    cublasStpmv(char uplo, char trans, char diag, int n, const float* AP, float* x, int incx) {
    status__ = mcblasStpmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, AP, x, incx);
}

static void
    cublasDtpmv(char uplo, char trans, char diag, int n, const double* AP, double* x, int incx) {
    status__ = mcblasDtpmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, AP, x, incx);
}

static void cublasCtpmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const cuComplex* AP,
                        cuComplex* x,
                        int incx) {
    status__ = mcblasCtpmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, AP, x, incx);
}

static void cublasZtpmv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const cuDoubleComplex* AP,
                        cuDoubleComplex* x,
                        int incx) {
    status__ = mcblasZtpmv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, AP, x, incx);
}
/*------------------------------------------------------------------------*/
/* TRSV */
static void cublasStrsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const float* A,
                        int lda,
                        float* x,
                        int incx) {
    status__ = mcblasStrsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, A, lda, x, incx);
}

static void cublasDtrsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const double* A,
                        int lda,
                        double* x,
                        int incx) {
    status__ = mcblasDtrsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, A, lda, x, incx);
}

static void cublasCtrsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const cuComplex* A,
                        int lda,
                        cuComplex* x,
                        int incx) {
    status__ = mcblasCtrsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, A, lda, x, incx);
}

static void cublasZtrsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const cuDoubleComplex* A,
                        int lda,
                        cuDoubleComplex* x,
                        int incx) {
    status__ = mcblasZtrsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, A, lda, x, incx);
}
/*------------------------------------------------------------------------*/
/* TPSV */
static void
    cublasStpsv(char uplo, char trans, char diag, int n, const float* AP, float* x, int incx) {
    status__ = mcblasStpsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, AP, x, incx);
}

static void
    cublasDtpsv(char uplo, char trans, char diag, int n, const double* AP, double* x, int incx) {
    status__ = mcblasDtpsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, AP, x, incx);
}

static void cublasCtpsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const cuComplex* AP,
                        cuComplex* x,
                        int incx) {
    status__ = mcblasCtpsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, AP, x, incx);
}

static void cublasZtpsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        const cuDoubleComplex* AP,
                        cuDoubleComplex* x,
                        int incx) {
    status__ = mcblasZtpsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, AP, x, incx);
}
/*------------------------------------------------------------------------*/
/* TBSV */
static void cublasStbsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        int k,
                        const float* A,
                        int lda,
                        float* x,
                        int incx) {
    status__ = mcblasStbsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, k, A, lda, x, incx);
}

static void cublasDtbsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        int k,
                        const double* A,
                        int lda,
                        double* x,
                        int incx) {
    status__ = mcblasDtbsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, k, A, lda, x, incx);
}
static void cublasCtbsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        int k,
                        const cuComplex* A,
                        int lda,
                        cuComplex* x,
                        int incx) {
    status__ = mcblasCtbsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, k, A, lda, x, incx);
}

static void cublasZtbsv(char uplo,
                        char trans,
                        char diag,
                        int n,
                        int k,
                        const cuDoubleComplex* A,
                        int lda,
                        cuDoubleComplex* x,
                        int incx) {
    status__ = mcblasZtbsv(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans),
                           char2mcblas_diagonal(diag), n, k, A, lda, x, incx);
}
/*------------------------------------------------------------------------*/
/* SYMV/HEMV */
static void cublasSsymv(char uplo,
                        int n,
                        float alpha,
                        const float* A,
                        int lda,
                        const float* x,
                        int incx,
                        float beta,
                        float* y,
                        int incy) {
    status__ =
        mcblasSsymv(handle__, char2mcblas_fill(uplo), n, &alpha, A, lda, x, incx, &beta, y, incy);
}
static void cublasDsymv(char uplo,
                        int n,
                        double alpha,
                        const double* A,
                        int lda,
                        const double* x,
                        int incx,
                        double beta,
                        double* y,
                        int incy) {
    status__ =
        mcblasDsymv(handle__, char2mcblas_fill(uplo), n, &alpha, A, lda, x, incx, &beta, y, incy);
}
static void cublasChemv(char uplo,
                        int n,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        const cuComplex* x,
                        int incx,
                        cuComplex beta,
                        cuComplex* y,
                        int incy) {
    status__ =
        mcblasChemv(handle__, char2mcblas_fill(uplo), n, &alpha, A, lda, x, incx, &beta, y, incy);
}
static void cublasZhemv(char uplo,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        const cuDoubleComplex* x,
                        int incx,
                        cuDoubleComplex beta,
                        cuDoubleComplex* y,
                        int incy) {
    status__ =
        mcblasZhemv(handle__, char2mcblas_fill(uplo), n, &alpha, A, lda, x, incx, &beta, y, incy);
}
/*------------------------------------------------------------------------*/
/* SBMV/HBMV */
static void cublasSsbmv(char uplo,
                        int n,
                        int k,
                        float alpha,
                        const float* A,
                        int lda,
                        const float* x,
                        int incx,
                        float beta,
                        float* y,
                        int incy) {
    status__ = mcblasSsbmv(handle__, char2mcblas_fill(uplo), n, k, &alpha, A, lda, x, incx, &beta,
                           y, incy);
}
static void cublasDsbmv(char uplo,
                        int n,
                        int k,
                        double alpha,
                        const double* A,
                        int lda,
                        const double* x,
                        int incx,
                        double beta,
                        double* y,
                        int incy) {
    status__ = mcblasDsbmv(handle__, char2mcblas_fill(uplo), n, k, &alpha, A, lda, x, incx, &beta,
                           y, incy);
}
static void cublasChbmv(char uplo,
                        int n,
                        int k,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        const cuComplex* x,
                        int incx,
                        cuComplex beta,
                        cuComplex* y,
                        int incy) {
    status__ = mcblasChbmv(handle__, char2mcblas_fill(uplo), n, k, &alpha, A, lda, x, incx, &beta,
                           y, incy);
}
static void cublasZhbmv(char uplo,
                        int n,
                        int k,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        const cuDoubleComplex* x,
                        int incx,
                        cuDoubleComplex beta,
                        cuDoubleComplex* y,
                        int incy) {
    status__ = mcblasZhbmv(handle__, char2mcblas_fill(uplo), n, k, &alpha, A, lda, x, incx, &beta,
                           y, incy);
}
/*------------------------------------------------------------------------*/
/* SPMV/HPMV */
static void cublasSspmv(char uplo,
                        int n,
                        float alpha,
                        const float* AP,
                        const float* x,
                        int incx,
                        float beta,
                        float* y,
                        int incy) {
    status__ =
        mcblasSspmv(handle__, char2mcblas_fill(uplo), n, &alpha, AP, x, incx, &beta, y, incy);
}
static void cublasDspmv(char uplo,
                        int n,
                        double alpha,
                        const double* AP,
                        const double* x,
                        int incx,
                        double beta,
                        double* y,
                        int incy) {
    status__ =
        mcblasDspmv(handle__, char2mcblas_fill(uplo), n, &alpha, AP, x, incx, &beta, y, incy);
}
static void cublasChpmv(char uplo,
                        int n,
                        cuComplex alpha,
                        const cuComplex* AP,
                        const cuComplex* x,
                        int incx,
                        cuComplex beta,
                        cuComplex* y,
                        int incy) {
    status__ =
        mcblasChpmv(handle__, char2mcblas_fill(uplo), n, &alpha, AP, x, incx, &beta, y, incy);
}
static void cublasZhpmv(char uplo,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* AP,
                        const cuDoubleComplex* x,
                        int incx,
                        cuDoubleComplex beta,
                        cuDoubleComplex* y,
                        int incy) {
    status__ =
        mcblasZhpmv(handle__, char2mcblas_fill(uplo), n, &alpha, AP, x, incx, &beta, y, incy);
}

/*------------------------------------------------------------------------*/
/* GER */
static void cublasSger(int m,
                       int n,
                       float alpha,
                       const float* x,
                       int incx,
                       const float* y,
                       int incy,
                       float* A,
                       int lda) {
    status__ = mcblasSger(handle__, m, n, &alpha, x, incx, y, incy, A, lda);
}
static void cublasDger(int m,
                       int n,
                       double alpha,
                       const double* x,
                       int incx,
                       const double* y,
                       int incy,
                       double* A,
                       int lda) {
    status__ = mcblasDger(handle__, m, n, &alpha, x, incx, y, incy, A, lda);
}

static void cublasCgeru(int m,
                        int n,
                        cuComplex alpha,
                        const cuComplex* x,
                        int incx,
                        const cuComplex* y,
                        int incy,
                        cuComplex* A,
                        int lda) {
    status__ = mcblasCgeru(handle__, m, n, &alpha, x, incx, y, incy, A, lda);
}
static void cublasCgerc(int m,
                        int n,
                        cuComplex alpha,
                        const cuComplex* x,
                        int incx,
                        const cuComplex* y,
                        int incy,
                        cuComplex* A,
                        int lda) {
    status__ = mcblasCgerc(handle__, m, n, &alpha, x, incx, y, incy, A, lda);
}
static void cublasZgeru(int m,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* x,
                        int incx,
                        const cuDoubleComplex* y,
                        int incy,
                        cuDoubleComplex* A,
                        int lda) {
    status__ = mcblasZgeru(handle__, m, n, &alpha, x, incx, y, incy, A, lda);
}
static void cublasZgerc(int m,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* x,
                        int incx,
                        const cuDoubleComplex* y,
                        int incy,
                        cuDoubleComplex* A,
                        int lda) {
    status__ = mcblasZgerc(handle__, m, n, &alpha, x, incx, y, incy, A, lda);
}
/*------------------------------------------------------------------------*/
/* SYR/HER */
static void cublasSsyr(char uplo, int n, float alpha, const float* x, int incx, float* A, int lda) {
    status__ = mcblasSsyr(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, A, lda);
}
static void
    cublasDsyr(char uplo, int n, double alpha, const double* x, int incx, double* A, int lda) {
    status__ = mcblasDsyr(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, A, lda);
}

static void
    cublasCher(char uplo, int n, float alpha, const cuComplex* x, int incx, cuComplex* A, int lda) {
    status__ = mcblasCher(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, A, lda);
}
static void cublasZher(char uplo,
                       int n,
                       double alpha,
                       const cuDoubleComplex* x,
                       int incx,
                       cuDoubleComplex* A,
                       int lda) {
    status__ = mcblasZher(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, A, lda);
}

/*------------------------------------------------------------------------*/
/* SPR/HPR */
static void cublasSspr(char uplo, int n, float alpha, const float* x, int incx, float* AP) {
    status__ = mcblasSspr(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, AP);
}
static void cublasDspr(char uplo, int n, double alpha, const double* x, int incx, double* AP) {
    status__ = mcblasDspr(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, AP);
}
static void cublasChpr(char uplo, int n, float alpha, const cuComplex* x, int incx, cuComplex* AP) {
    status__ = mcblasChpr(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, AP);
}
static void cublasZhpr(char uplo,
                       int n,
                       double alpha,
                       const cuDoubleComplex* x,
                       int incx,
                       cuDoubleComplex* AP) {
    status__ = mcblasZhpr(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, AP);
}
/*------------------------------------------------------------------------*/
/* SYR2/HER2 */
static void cublasSsyr2(char uplo,
                        int n,
                        float alpha,
                        const float* x,
                        int incx,
                        const float* y,
                        int incy,
                        float* A,
                        int lda) {
    status__ = mcblasSsyr2(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, y, incy, A, lda);
}
static void cublasDsyr2(char uplo,
                        int n,
                        double alpha,
                        const double* x,
                        int incx,
                        const double* y,
                        int incy,
                        double* A,
                        int lda) {
    status__ = mcblasDsyr2(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, y, incy, A, lda);
}
static void cublasCher2(char uplo,
                        int n,
                        cuComplex alpha,
                        const cuComplex* x,
                        int incx,
                        const cuComplex* y,
                        int incy,
                        cuComplex* A,
                        int lda) {
    status__ = mcblasCher2(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, y, incy, A, lda);
}
static void cublasZher2(char uplo,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* x,
                        int incx,
                        const cuDoubleComplex* y,
                        int incy,
                        cuDoubleComplex* A,
                        int lda) {
    status__ = mcblasZher2(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, y, incy, A, lda);
}

/*------------------------------------------------------------------------*/
/* SPR2/HPR2 */
static void cublasSspr2(char uplo,
                        int n,
                        float alpha,
                        const float* x,
                        int incx,
                        const float* y,
                        int incy,
                        float* AP) {
    status__ = mcblasSspr2(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, y, incy, AP);
}
static void cublasDspr2(char uplo,
                        int n,
                        double alpha,
                        const double* x,
                        int incx,
                        const double* y,
                        int incy,
                        double* AP) {
    status__ = mcblasDspr2(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, y, incy, AP);
}
static void cublasChpr2(char uplo,
                        int n,
                        cuComplex alpha,
                        const cuComplex* x,
                        int incx,
                        const cuComplex* y,
                        int incy,
                        cuComplex* AP) {
    status__ = mcblasChpr2(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, y, incy, AP);
}
static void cublasZhpr2(char uplo,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* x,
                        int incx,
                        const cuDoubleComplex* y,
                        int incy,
                        cuDoubleComplex* AP) {
    status__ = mcblasZhpr2(handle__, char2mcblas_fill(uplo), n, &alpha, x, incx, y, incy, AP);
}
/* ------------------------BLAS3 Functions ------------------------------- */
/* GEMM */
static void cublasSgemm(char transa,
                        char transb,
                        int m,
                        int n,
                        int k,
                        float alpha,
                        const float* A,
                        int lda,
                        const float* B,
                        int ldb,
                        float beta,
                        float* C,
                        int ldc) {
    status__ = mcblasSgemm(handle__, char2mcblas_operation(transa), char2mcblas_operation(transb),
                           m, n, k, &alpha, A, lda, B, ldb, &beta, C, ldc);
}
static void cublasDgemm(char transa,
                        char transb,
                        int m,
                        int n,
                        int k,
                        double alpha,
                        const double* A,
                        int lda,
                        const double* B,
                        int ldb,
                        double beta,
                        double* C,
                        int ldc) {
    status__ = mcblasDgemm(handle__, char2mcblas_operation(transa), char2mcblas_operation(transb),
                           m, n, k, &alpha, A, lda, B, ldb, &beta, C, ldc);
}
static void cublasCgemm(char transa,
                        char transb,
                        int m,
                        int n,
                        int k,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        const cuComplex* B,
                        int ldb,
                        cuComplex beta,
                        cuComplex* C,
                        int ldc) {
    status__ = mcblasCgemm(handle__, char2mcblas_operation(transa), char2mcblas_operation(transb),
                           m, n, k, &alpha, A, lda, B, ldb, &beta, C, ldc);
}
static void cublasZgemm(char transa,
                        char transb,
                        int m,
                        int n,
                        int k,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        const cuDoubleComplex* B,
                        int ldb,
                        cuDoubleComplex beta,
                        cuDoubleComplex* C,
                        int ldc) {
    status__ = mcblasZgemm(handle__, char2mcblas_operation(transa), char2mcblas_operation(transb),
                           m, n, k, &alpha, A, lda, B, ldb, &beta, C, ldc);
}
/* -------------------------------------------------------*/
/* SYRK */
static void cublasSsyrk(char uplo,
                        char trans,
                        int n,
                        int k,
                        float alpha,
                        const float* A,
                        int lda,
                        float beta,
                        float* C,
                        int ldc) {
    status__ = mcblasSsyrk(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                           &alpha, A, lda, &beta, C, ldc);
}
static void cublasDsyrk(char uplo,
                        char trans,
                        int n,
                        int k,
                        double alpha,
                        const double* A,
                        int lda,
                        double beta,
                        double* C,
                        int ldc) {
    status__ = mcblasDsyrk(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                           &alpha, A, lda, &beta, C, ldc);
}

static void cublasCsyrk(char uplo,
                        char trans,
                        int n,
                        int k,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        cuComplex beta,
                        cuComplex* C,
                        int ldc) {
    status__ = mcblasCsyrk(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                           &alpha, A, lda, &beta, C, ldc);
}
static void cublasZsyrk(char uplo,
                        char trans,
                        int n,
                        int k,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        cuDoubleComplex beta,
                        cuDoubleComplex* C,
                        int ldc) {
    status__ = mcblasZsyrk(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                           &alpha, A, lda, &beta, C, ldc);
}
/* ------------------------------------------------------- */
/* HERK */
static void cublasCherk(char uplo,
                        char trans,
                        int n,
                        int k,
                        float alpha,
                        const cuComplex* A,
                        int lda,
                        float beta,
                        cuComplex* C,
                        int ldc) {
    status__ = mcblasCherk(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                           &alpha, A, lda, &beta, C, ldc);
}
static void cublasZherk(char uplo,
                        char trans,
                        int n,
                        int k,
                        double alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        double beta,
                        cuDoubleComplex* C,
                        int ldc) {
    status__ = mcblasZherk(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                           &alpha, A, lda, &beta, C, ldc);
}
/* ------------------------------------------------------- */
/* SYR2K */
static void cublasSsyr2k(char uplo,
                         char trans,
                         int n,
                         int k,
                         float alpha,
                         const float* A,
                         int lda,
                         const float* B,
                         int ldb,
                         float beta,
                         float* C,
                         int ldc) {
    status__ = mcblasSsyr2k(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                            &alpha, A, lda, B, ldb, &beta, C, ldc);
}

static void cublasDsyr2k(char uplo,
                         char trans,
                         int n,
                         int k,
                         double alpha,
                         const double* A,
                         int lda,
                         const double* B,
                         int ldb,
                         double beta,
                         double* C,
                         int ldc) {
    status__ = mcblasDsyr2k(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                            &alpha, A, lda, B, ldb, &beta, C, ldc);
}
static void cublasCsyr2k(char uplo,
                         char trans,
                         int n,
                         int k,
                         cuComplex alpha,
                         const cuComplex* A,
                         int lda,
                         const cuComplex* B,
                         int ldb,
                         cuComplex beta,
                         cuComplex* C,
                         int ldc) {
    status__ = mcblasCsyr2k(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                            &alpha, A, lda, B, ldb, &beta, C, ldc);
}

static void cublasZsyr2k(char uplo,
                         char trans,
                         int n,
                         int k,
                         cuDoubleComplex alpha,
                         const cuDoubleComplex* A,
                         int lda,
                         const cuDoubleComplex* B,
                         int ldb,
                         cuDoubleComplex beta,
                         cuDoubleComplex* C,
                         int ldc) {
    status__ = mcblasZsyr2k(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                            &alpha, A, lda, B, ldb, &beta, C, ldc);
}
/* ------------------------------------------------------- */
/* HER2K */
static void cublasCher2k(char uplo,
                         char trans,
                         int n,
                         int k,
                         cuComplex alpha,
                         const cuComplex* A,
                         int lda,
                         const cuComplex* B,
                         int ldb,
                         float beta,
                         cuComplex* C,
                         int ldc) {
    status__ = mcblasCher2k(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                            &alpha, A, lda, B, ldb, &beta, C, ldc);
}

static void cublasZher2k(char uplo,
                         char trans,
                         int n,
                         int k,
                         cuDoubleComplex alpha,
                         const cuDoubleComplex* A,
                         int lda,
                         const cuDoubleComplex* B,
                         int ldb,
                         double beta,
                         cuDoubleComplex* C,
                         int ldc) {
    status__ = mcblasZher2k(handle__, char2mcblas_fill(uplo), char2mcblas_operation(trans), n, k,
                            &alpha, A, lda, B, ldb, &beta, C, ldc);
}

/*------------------------------------------------------------------------*/
/* SYMM*/
static void cublasSsymm(char side,
                        char uplo,
                        int m,
                        int n,
                        float alpha,
                        const float* A,
                        int lda,
                        const float* B,
                        int ldb,
                        float beta,
                        float* C,
                        int ldc) {
    status__ = mcblasSsymm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo), m, n, &alpha,
                           A, lda, B, ldb, &beta, C, ldc);
}
static void cublasDsymm(char side,
                        char uplo,
                        int m,
                        int n,
                        double alpha,
                        const double* A,
                        int lda,
                        const double* B,
                        int ldb,
                        double beta,
                        double* C,
                        int ldc) {
    status__ = mcblasDsymm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo), m, n, &alpha,
                           A, lda, B, ldb, &beta, C, ldc);
}

static void cublasCsymm(char side,
                        char uplo,
                        int m,
                        int n,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        const cuComplex* B,
                        int ldb,
                        cuComplex beta,
                        cuComplex* C,
                        int ldc) {
    status__ = mcblasCsymm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo), m, n, &alpha,
                           A, lda, B, ldb, &beta, C, ldc);
}

static void cublasZsymm(char side,
                        char uplo,
                        int m,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        const cuDoubleComplex* B,
                        int ldb,
                        cuDoubleComplex beta,
                        cuDoubleComplex* C,
                        int ldc) {
    status__ = mcblasZsymm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo), m, n, &alpha,
                           A, lda, B, ldb, &beta, C, ldc);
}
/*------------------------------------------------------------------------*/
/* HEMM*/
static void cublasChemm(char side,
                        char uplo,
                        int m,
                        int n,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        const cuComplex* B,
                        int ldb,
                        cuComplex beta,
                        cuComplex* C,
                        int ldc) {
    status__ = mcblasChemm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo), m, n, &alpha,
                           A, lda, B, ldb, &beta, C, ldc);
}
static void cublasZhemm(char side,
                        char uplo,
                        int m,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        const cuDoubleComplex* B,
                        int ldb,
                        cuDoubleComplex beta,
                        cuDoubleComplex* C,
                        int ldc) {
    status__ = mcblasZhemm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo), m, n, &alpha,
                           A, lda, B, ldb, &beta, C, ldc);
}

/*------------------------------------------------------------------------*/
/* TRSM*/
static void cublasStrsm(char side,
                        char uplo,
                        char transa,
                        char diag,
                        int m,
                        int n,
                        float alpha,
                        const float* A,
                        int lda,
                        float* B,
                        int ldb) {
    status__ = mcblasStrsm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo),
                           char2mcblas_operation(transa), char2mcblas_diagonal(diag), m, n, &alpha,
                           A, lda, B, ldb);
}

static void cublasDtrsm(char side,
                        char uplo,
                        char transa,
                        char diag,
                        int m,
                        int n,
                        double alpha,
                        const double* A,
                        int lda,
                        double* B,
                        int ldb) {
    status__ = mcblasDtrsm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo),
                           char2mcblas_operation(transa), char2mcblas_diagonal(diag), m, n, &alpha,
                           A, lda, B, ldb);
}

static void cublasCtrsm(char side,
                        char uplo,
                        char transa,
                        char diag,
                        int m,
                        int n,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        cuComplex* B,
                        int ldb) {
    status__ = mcblasCtrsm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo),
                           char2mcblas_operation(transa), char2mcblas_diagonal(diag), m, n, &alpha,
                           A, lda, B, ldb);
}

static void cublasZtrsm(char side,
                        char uplo,
                        char transa,
                        char diag,
                        int m,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        cuDoubleComplex* B,
                        int ldb) {
    status__ = mcblasZtrsm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo),
                           char2mcblas_operation(transa), char2mcblas_diagonal(diag), m, n, &alpha,
                           A, lda, B, ldb);
}
/*------------------------------------------------------------------------*/
/* TRMM*/
static void cublasStrmm(char side,
                        char uplo,
                        char transa,
                        char diag,
                        int m,
                        int n,
                        float alpha,
                        const float* A,
                        int lda,
                        float* B,
                        int ldb) {
    status__ = mcblasStrmm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo),
                           char2mcblas_operation(transa), char2mcblas_diagonal(diag), m, n, &alpha,
                           A, lda, B, ldb, B, ldb);
}
static void cublasDtrmm(char side,
                        char uplo,
                        char transa,
                        char diag,
                        int m,
                        int n,
                        double alpha,
                        const double* A,
                        int lda,
                        double* B,
                        int ldb) {
    status__ = mcblasDtrmm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo),
                           char2mcblas_operation(transa), char2mcblas_diagonal(diag), m, n, &alpha,
                           A, lda, B, ldb, B, ldb);
}
static void cublasCtrmm(char side,
                        char uplo,
                        char transa,
                        char diag,
                        int m,
                        int n,
                        cuComplex alpha,
                        const cuComplex* A,
                        int lda,
                        cuComplex* B,
                        int ldb) {
    status__ = mcblasCtrmm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo),
                           char2mcblas_operation(transa), char2mcblas_diagonal(diag), m, n, &alpha,
                           A, lda, B, ldb, B, ldb);
}
static void cublasZtrmm(char side,
                        char uplo,
                        char transa,
                        char diag,
                        int m,
                        int n,
                        cuDoubleComplex alpha,
                        const cuDoubleComplex* A,
                        int lda,
                        cuDoubleComplex* B,
                        int ldb) {
    status__ = mcblasZtrmm(handle__, char2mcblas_side(side), char2mcblas_fill(uplo),
                           char2mcblas_operation(transa), char2mcblas_diagonal(diag), m, n, &alpha,
                           A, lda, B, ldb, B, ldb);
}

#if defined(__cplusplus)
}
#endif /* __cplusplus */
